package com.xiao.rpc;

import com.xiao.rpc.config.RegistryConfig;
import com.xiao.rpc.config.RpcConfig;
import com.xiao.rpc.constant.RpcConstant;
import com.xiao.rpc.registry.Registry;
import com.xiao.rpc.registry.RegistryFactory;
import com.xiao.rpc.utils.ConfigUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * RPC框架启动入口
 *
 * RPC启动入口; 存放了项目全局用到的变量，并提供get方法
 * 单例模式实现：基于双检锁单例模式
 */
@Slf4j
public class RpcApplication {

    private static volatile RpcConfig rpcConfig;

    /**
     * 框架初始化，支持传入自定义配置
     *
     * @param newRpcConfig
     */
    public static void init(RpcConfig newRpcConfig){
        rpcConfig = newRpcConfig;
        log.info("rpc 初始化成功，配置config= {}", newRpcConfig.toString());
        // 注册中心初始化
        RegistryConfig registryConfig = rpcConfig.getRegistryConfig();
        Registry registry = RegistryFactory.getInstance(registryConfig.getRegistryType());
        registry.init(registryConfig);
        log.info("注册中心初始化成功, 配置config= {}", registryConfig);

        // 创建并注册 Shutdown Hook，程序正常退出时，会执行destroy方法
        Runtime.getRuntime().addShutdownHook(new Thread(registry::destroy));
    }

    /**
     * 初始化
     */
    public static void init(){
        RpcConfig newRpcConfig;
        try {
            newRpcConfig = ConfigUtil.loadConfig(RpcConfig.class, RpcConstant.DEFAULT_CONFIG_PREFIX);
        } catch (Exception e) {
            // 加载失败，使用默认配置
            newRpcConfig = new RpcConfig();
        }
        init(newRpcConfig);
    }

    /**
     * 获取配置
     *
     * @return
     */
    public static RpcConfig getRpcConfig() {
        if (rpcConfig == null) {
            synchronized (RpcApplication.class) {
                if (rpcConfig == null) {
                    init();
                }
            }
        }
        return rpcConfig;
    }
}
